package com.kb.erp.service.impl;


import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.util.StringUtils;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kb.erp.entity.quote.*;
import com.kb.erp.mapper.pg.QuoteCountMapper;
import com.kb.erp.service.QuoteService;
import com.kb.erp.service.digi.DigikeyServiceImpl;
import groovy.util.logging.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

@Service
@DS("pg")
@Slf4j
public class QuoteServiceImpl implements QuoteService {
    private static Logger logger = LoggerFactory.getLogger(QuoteServiceImpl.class);
    @Resource
    private QuoteCountMapper countMapper;

    @Resource(name = "componentExecutor")
    private ThreadPoolExecutor componentExecutor;

    private String clientID = "lnGfrAAGJZMWdzRYe7eJTEn5tgEl0eKc";

    private String client_secret = "1aUJX2eqqnh9oaja";

    private String grant_type = "client_credentials";

    private String urlprefix = "http://192.168.10.92";

    @Resource
    private DigikeyServiceImpl digikeyServiceImpl;

    public static String filterZeroWidthSpace(String input) {
        return input.replaceAll("[\\u200B\\u0020\\u3000]+", "");
    }

    public List<QuoteVO> singleRequest(QuoteTO to) throws IOException {

        Integer qtyTem = to.getQty();

        List<QuoteVO> result = new ArrayList<>();

// 如果没传 `source`，就全选
        if (StringUtils.isBlank(to.getSource())) {
            to.setSource("1,2,3,4,5");
        }

        String source = to.getSource();
        String[] stringArray = source.split(",");

// 将字符串数组转换为 Integer 类型的 List
        List<Integer> integerList = Arrays.stream(stringArray)
                .map(Integer::parseInt)
                .collect(Collectors.toList());

// 调用 Mapper 方法插入或更新记录
        countMapper.countAdd(integerList);


        //如果有1，请求昴氏
        if (to.getSource().contains("1")) {
            // 准备请求的URL
            String url = "http://192.168.10.92:8010/mouser.ashx?cmd=enquiry";


// 准备要发送的参数（x-www-form-urlencoded 格式）
            String postData = "mfc=" + URLEncoder.encode(to.getNo().replace("＋", "+"), "UTF-8");
            // 对mfc进行URL编码，并设置currcode为USD

// 发送POST请求

            String str = HttpUtil.post(url, postData); // 假设HttpUtil有post方法支持这种格式

// 解析返回的JSON字符串
            ObjectMapper mapper = new ObjectMapper();
            Response response = mapper.readValue(str, Response.class);


            //过滤，处理brand字段
            String filterBrand = to.getBrand();
            if (response.getData() != null) {
//                        response.getData().removeIf(item -> !item.getVen_mfc_mode().toLowerCase().contains(to.getNo().toLowerCase()));
                if (StringUtils.isNotBlank(filterBrand)) {
                    response.getData().removeIf(item -> !item.getVen_brand().toLowerCase().contains(filterBrand.toLowerCase()));
                }
            }

//                if(response.getData()!=null){
//                    response.getData().removeIf(item ->item.getQuantityAvailable()==null|| !(Integer.valueOf(item.getQuantityAvailable())>0));
//                }


            //如果过滤后还有
            if (response.getData() != null && response.getData().size() > 0) {

                response.adjustPricesForInflation();

                QuoteVO title = new QuoteVO();
                title.setSource("昴氏");


                List<QuoteVO> children = new ArrayList<>();


                for (Response.Item item : response.getData()) {
                    item.sortPricingLists();
                    QuoteVO tem = new QuoteVO();


                    List<Response.Item.Compliance> productCompliance = item.getProductCompliance();
                    if (!productCompliance.isEmpty()) {
                        // 使用流式查找
                        productCompliance.stream()
                                .filter(attr -> "ECCN".equals(attr.getComplianceName()))
                                .findFirst()
                                .ifPresent(attr -> tem.setEccn(attr.getComplianceValue()));
                    }


                    tem.setSource("昴氏");

                    Optional<String> attributeValue = item.getVen_package().stream()
                            .filter(attr -> "封装".equals(attr.getAttributeName()))  // 过滤出 AttributeName 为 "封装" 的元素
                            .map(Response.Item.MouseAttribute::getAttributeValue)  // 提取 AttributeValue
                            .findFirst();  // 获取第一个匹配的结果

                    if (attributeValue.isPresent())
                        tem.setVenPackage(attributeValue.get());

                    tem.setPart(item.getVen_partnumber());
                    tem.setMfc(item.getVen_mfc_mode());
                    tem.setQty(to.getQty());
                    tem.setBrand(item.getVen_brand());
                    tem.setModel(item.getVen_desc_dtl());
                    tem.setCurrency(to.getCurrency());
                    tem.setInventory(item.getQuantityAvailable());
                    tem.setMinNum(Integer.valueOf(item.getMinimumOrderQuantity()));
                    tem.setPrice(item.generatePriceString());
                    tem.setPrice2(item.generatePriceString2());

                    tem.setPriceNum(item.generatePriceString3());

                    if (to.getQty() != null && item.getQuantityAvailable() != null) {
                        Integer temNum = (to.getQty() > Integer.valueOf(item.getQuantityAvailable()) ? Integer.valueOf(item.getQuantityAvailable()) : to.getQty());
                        findMatchingPrices(item, temNum, tem);
                    }

//
                    children.add(tem);
                }
                title.setChildren(children);
                result.add(title);
            }


        }

        //如果有2，请求得捷
        if (to.getSource().contains("2")) {
            // 准备请求的URL
            String urlString = urlprefix + ":9037/digikey/getQuote";


//                    String urlString = "http://192.168.51.137:9037/digikey/getQuote";
            URL url = new URL(urlString);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();

            // Set up the connection properties
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/json; utf-8");
            conn.setRequestProperty("Accept", "application/json");
            conn.setDoOutput(true);

            // Create the JSON object to send
            String currency;
            if (Objects.equals(to.getCurrency(), "RMB")) {
                currency = "CNY";
            } else {
                currency = "USD";
            }

            String jsonInputString = "{ \"keyWord\": \"" + to.getNo().replace("\\", "") + "\", \"currency\": \"" + currency + "\" }";
            try (OutputStream os = conn.getOutputStream()) {
                byte[] input = jsonInputString.getBytes("utf-8");
                os.write(input, 0, input.length);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

            // Check response
            int responseCode = conn.getResponseCode();
            System.out.println("Response Code: " + responseCode);

            if (responseCode == HttpURLConnection.HTTP_OK) {
                // Read the response
                try (InputStream is = conn.getInputStream();
                     BufferedReader reader = new BufferedReader(new InputStreamReader(is, "utf-8"))) {

                    StringBuilder response = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null) {
                        response.append(line).append("\n");
                    }

                    // Convert response to a string
                    String jsonResponse = response.toString();
                    System.out.println("Response JSON: " + jsonResponse);


                    ObjectMapper mapper = new ObjectMapper();

                    try {
                        ResponseDeJie4 response1 = mapper.readValue(jsonResponse, ResponseDeJie4.class);

                        if (response1 != null) {

                            QuoteVO title = new QuoteVO();
                            List<QuoteVO> children = new ArrayList<>();
                            title.setSource("得捷");


                            if (response1.getData() == null || response1.getData().isEmpty()) {
//                                        digikeyServiceImpl.updateTokenNew();
                            }

                            for (ResponseDeJie4.ProductWrapper item : response1.getData()) {

                                int subnum = 0;
                                if (to.getQty() != null)
                                    subnum = qtyTem;


                                String filterBrand = to.getBrand();


                                if (item == null || item.getProduct() == null) {
                                    continue;
                                }

                                ResponseDeJie4.Product product = item.getProduct();
                                if (product != null) {


                                    sortProductVariations(product.getProductVariations());

                                    boolean find = product.getProductVariations().stream()
                                            .filter(variation -> variation.getPackageType() != null && !variation.getPackageType().getName().contains("Digi-Reel")) // 检查PackageType是否为null
                                            .mapToInt(variation -> variation.getQuantityAvailableforPackageType())
                                            .sum() < product.getQuantityAvailable();

                                    for (ResponseDeJie4.ProductVariation variation : product.getProductVariations()) {

                                        if (variation != null) {

                                            if (StringUtils.isNotBlank(filterBrand) && !product.getManufacturer().getName().toLowerCase().contains(filterBrand.toLowerCase())) {
                                                continue;
                                            }

                                            QuoteVO tem = new QuoteVO();


                                            List<ResponseDeJie4.Parameters> parameters = item.getProduct().getParameters();

                                            // 使用流 (Stream) 查找 parameterId 为 405 的 valueText
                                            Optional<String> valueText = parameters.stream()
                                                    .filter(param -> param.getParameterId() == 405)  // 筛选出 parameterId 为 405 的参数
                                                    .map(ResponseDeJie4.Parameters::getValueText)  // 提取 valueText
                                                    .findFirst();  // 找到第一个匹配的项

                                            if (valueText.isPresent()) {
                                                tem.setApplication(valueText.get());
                                            }


                                            tem.setMinNum(variation.generateMinNum());
                                            if (product.getClassifications() != null)
                                                tem.setEccn(product.getClassifications().getExportControlClassNumber());

//                                                    tem.setMinNum(variation.getMinimumOrderQuantity());
                                            if (variation != null && variation.getPackageType() != null && variation.getPackageType().getName() != null) {
                                                tem.setVenPackage(variation.getPackageType().getName());
                                            }

                                            tem.setMfc(product.getManufacturerProductNumber());
                                            tem.setPrice(variation.generatePriceString());
                                            tem.setPrice2(variation.generatePriceString2());
                                            tem.setPriceNum(variation.generatePriceString3());

                                            tem.setQty(to.getQty());

                                            tem.setInventory(String.valueOf(variation.getQuantityAvailableforPackageType()));
                                            if (to.getQty() != null) {


                                                //卷带
                                                if (tem.getVenPackage() != null && (tem.getVenPackage().contains("TR") || tem.getVenPackage().contains("TB"))) {


//                                                             if(to.getQty()>variation.getQuantityAvailableforPackageType()){
//                                                            variation.findBestPricing(variation.getQuantityAvailableforPackageType(),tem,currency,to.getQty());
//                                                        }else{
//                                                            variation.findBestPricing(to.getQty(),tem,currency,to.getQty());
//                                                        }


                                                    //如果库存小于询价数量，以库存为主
                                                    if (to.getQty() > variation.getQuantityAvailableforPackageType()) {
                                                        to.setQty(variation.getQuantityAvailableforPackageType());
                                                    }

                                                    variation.findBestPricing(to.getQty(), tem, currency, to.getQty(), true);


                                                    if (tem.getResult() != null && StringUtils.isNotBlank(tem.getResult())) {

                                                        int i = Integer.parseInt(tem.getResult());
                                                        subnum = qtyTem - (to.getQty() / i) * i;

                                                        tem.setQty(Integer.valueOf(tem.getResult()));

                                                    }


                                                } else {

                                                    //得捷新情况，存在合作的商品，目前库存没有，但是可能会调度到此包装
                                                    if (variation.getQuantityAvailableforPackageType() == 0 && find) {
                                                        variation.setQuantityAvailableforPackageType(product.getQuantityAvailable());
                                                        tem.setInventory(String.valueOf(product.getQuantityAvailable()));
                                                    }

                                                    if (subnum > variation.getQuantityAvailableforPackageType()) {
                                                        variation.findBestPricing(variation.getQuantityAvailableforPackageType(), tem, currency, subnum, false);


                                                    } else {
                                                        variation.findBestPricing(subnum, tem, currency, subnum, false);
                                                    }
//
//                                                            variation.findBestPricing(subnum,tem,currency,subnum,false);
                                                    tem.setQty(subnum);

                                                }


                                            }

                                            tem.setPart(variation.getDigiKeyProductNumber());


                                            tem.setSource("得捷");
                                            tem.setModel(product.getDescription().getDetailedDescription());

                                            tem.setBrand(product.getManufacturer().getName());

                                            tem.setCurrency(to.getCurrency());


                                            children.add(tem);
                                        }


                                    }

                                }

                            }

                            if (children.size() > 0) {


                                title.setChildren(children);
                                result.add(title);
                            }


                        }
                        // 可以继续打印更多的细节或处理数据
                    } catch (IOException e) {
//                                digikeyServiceImpl.updateTokenNew();
                        System.out.println("Error parsing JSON data: " + e.getMessage());
                    }


                    // Process the response (e.g., parse JSON)

                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            } else {
                System.out.println("Request Failed.");
            }

            conn.disconnect();


        }

        //还原
        to.setQty(qtyTem);

//如果有3，请求易洛盟
        if (to.getSource().contains("3")) {
            // 准备请求的URL
            String url = "http://192.168.10.92:8010/element.ashx?cmd=enquiryex";

// 准备要发送的参数（x-www-form-urlencoded 格式）
            String postData = "code=" + URLEncoder.encode(to.getNo(), "UTF-8"); // 对code进行URL编码

// 发送POST请求
            String str = HttpUtil.post(url, postData); // 假设HttpUtil有post方法支持这种格式
            ObjectMapper mapper = new ObjectMapper();
            ResponseElement response = mapper.readValue(str, ResponseElement.class);
            String filterBrand = to.getBrand();

            Optional.ofNullable(response.getProducts())
                    .ifPresent(products -> products.stream()
                            .filter(product -> product.getPrices() != null)
                            .forEach(product -> product.getPrices().forEach(price -> {
                                BigDecimal calculatedPrice = price.calculatePrice();
                                price.setPrice(calculatedPrice);
                            })));


            if (StringUtils.isNotBlank(filterBrand) && response.getProducts() != null) {
                response.getProducts().removeIf(item -> !item.getBrandName().toLowerCase().contains(filterBrand.toLowerCase()));
            }

//                if(response.getProducts()!=null){
//                    response.getProducts().removeIf(item ->item.getStock()==null|| !(Integer.valueOf(item.getStock().getLevel())>0));
//                }

            //如果过滤后还有
            if (response.getProducts() != null && response.getProducts().size() > 0) {
                response.adjustPricesForInflation();
                QuoteVO title = new QuoteVO();
                title.setSource("易洛盟");


                List<QuoteVO> children = new ArrayList<>();

                for (ResponseElement.Product item : response.getProducts()) {

                    QuoteVO tem = new QuoteVO();
                    tem.setPart(item.getSku());
                    tem.setMfc(item.getTranslatedManufacturerPartNumber());
                    tem.setQty(to.getQty());
                    tem.setMinNum(item.getTranslatedMinimumOrderQuality());
                    tem.setVenPackage(item.getUnitOfMeasure());

                    List<ResponseElement.Product.Attr> attrs = item.getAttrs();
                    if (!attrs.isEmpty()) {
                        // 使用流式查找
                        attrs.stream()
                                .filter(attr -> "usEccn".equals(attr.getAttributeLabel()))
                                .findFirst()
                                .ifPresent(attr -> tem.setEccn(attr.getAttributeValue()));
                    }


                    tem.setSource("易洛盟");
                    tem.setModel(item.getDisplayName());
                    tem.setBrand(item.getBrandName());
                    tem.setPrice(formatPrices(item.getPrices()));
                    tem.setPrice2(formatPrices2(item.getStdPrices()));
                    tem.setCurrency(to.getCurrency());
                    tem.setPriceNum(formatPrices3(item.getPrices()));

                    tem.setInventory(Integer.valueOf(item.getStock().getLevel()).toString());

                    if (to.getQty() != null)
                        findPriceForValue(item.getPrices(),item.getStdPrices(), to.getQty(), tem);
                    children.add(tem);

                }
                title.setChildren(children);
                result.add(title);
            }

        }

//如果有4，请求云汉
        if (to.getSource().contains("4")) {
            // 准备请求的URL
            String urlString = urlprefix + ":9037/quote/query";
//                    String urlString = "http://192.168.51.137:9037/quote/query";
            URL url = new URL(urlString);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();

            // Set up the connection properties
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/json; utf-8");
            conn.setRequestProperty("Accept", "application/json");
            conn.setDoOutput(true);

            // Create the JSON object to send
            String jsonInputString = "{\"keyWord\": \"" + to.getNo() + "\"}";


            // Send JSON input
            try (OutputStream os = conn.getOutputStream()) {
                byte[] input = jsonInputString.getBytes("utf-8");
                os.write(input, 0, input.length);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

            // Check response
            int responseCode = conn.getResponseCode();
            System.out.println("Response Code: " + responseCode);

            if (responseCode == HttpURLConnection.HTTP_OK) {
                // Read the response
                try (InputStream is = conn.getInputStream();
                     BufferedReader reader = new BufferedReader(new InputStreamReader(is, "utf-8"))) {

                    StringBuilder response = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null) {
                        response.append(line).append("\n");
                    }

                    // Convert response to a string
                    String jsonResponse = response.toString();
                    System.out.println("Response JSON: " + jsonResponse);


                    ObjectMapper objectMapper = new ObjectMapper();
                    try {
                        // Parse the JSON response
                        JsonNode rootNode = objectMapper.readTree(jsonResponse);

                        // Extract the "data" array
                        JsonNode dataNode = rootNode.path("data");

                        // Check if "data" is an array
                        if (dataNode.isArray()) {
                            // Convert "data" array to List of Product objects
                            List<IqcProduct> products = objectMapper.readValue(
                                    dataNode.toString(),
                                    objectMapper.getTypeFactory().constructCollectionType(List.class, IqcProduct.class)
                            );
                            String filterBrand = to.getBrand();
                            if (StringUtils.isNotBlank(filterBrand)) {
                                products = products.stream()
                                        .filter(item -> item.getProMaf().toLowerCase().contains(filterBrand.toLowerCase()))
                                        .collect(Collectors.toList());
                            }

                            if (products != null && products.size() > 0) {
                                QuoteVO title = new QuoteVO();
                                title.setSource("云汉芯城");
                                List<QuoteVO> children = new ArrayList<>();

                                for (IqcProduct item : products) {

                                    QuoteVO tem = new QuoteVO();
                                    tem.setPart(String.valueOf(item.getSku()));
                                    tem.setMfc(item.getProName());
                                    tem.setQty(to.getQty());
                                    tem.setMinNum(item.getMoq());
                                    tem.setVenPackage(item.getPackageValue());
                                    tem.setSource("云汉芯城");
                                    tem.setModel(item.getProDesc());
                                    tem.setBrand(item.getProMaf());
                                    tem.setPrice(item.getRmbAsString(to.getCurrency()));
                                    tem.setPrice2(item.getRmbAsString(to.getCurrency()));
                                    tem.setCurrency(to.getCurrency());
                                    tem.setPriceNum(item.getNumsAsString());

                                    tem.setInventory(String.valueOf(item.getStock()));

                                    if (to.getQty() != null)
                                        findPriceForValue2(item, to.getQty(), tem, to.getCurrency());
                                    children.add(tem);

                                }
                                title.setChildren(children);
                                result.add(title);


                            }


                        }

                    } catch (IOException e) {
                        e.printStackTrace();
                    }


                    // Process the response (e.g., parse JSON)

                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            } else {
                System.out.println("Request Failed.");
            }

            conn.disconnect();


        }
//如果有5，请求圣禾堂
        try {
            if (to.getSource().contains("5")) {
                // 准备请求的URL
                String urlString = urlprefix + ":9037/SHTQuote/query";
                URL url = new URL(urlString);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();

                // Set up the connection properties
                conn.setRequestMethod("POST");
                conn.setRequestProperty("Content-Type", "application/json; utf-8");
                conn.setRequestProperty("Accept", "application/json");
                conn.setDoOutput(true);

                // Create the JSON object to send
                String jsonInputString = "{\"keyWord\": \"" + to.getNo() + "\"}";

                // Send JSON input
                try (OutputStream os = conn.getOutputStream()) {
                    byte[] input = jsonInputString.getBytes("utf-8");
                    os.write(input, 0, input.length);
                }

                // Check response
                int responseCode = conn.getResponseCode();
                System.out.println("Response Code: " + responseCode);

                if (responseCode == HttpURLConnection.HTTP_OK) {
                    // Read the response
                    try (InputStream is = conn.getInputStream();
                         BufferedReader reader = new BufferedReader(new InputStreamReader(is, "utf-8"))) {

                        StringBuilder response = new StringBuilder();
                        String line;
                        while ((line = reader.readLine()) != null) {
                            response.append(line).append("\n");
                        }

                        // Convert response to a string
                        String jsonResponse = response.toString();
                        System.out.println("Response JSON: " + jsonResponse);

                        ObjectMapper objectMapper = new ObjectMapper();
                        JsonNode rootNode = objectMapper.readTree(jsonResponse);

                        // Extract the "data" array
                        JsonNode dataNode = rootNode.path("data");

                        // Check if "data" is an array
                        if (dataNode.isArray()) {
                            // Convert "data" array to List of Product objects
                            List<GoodsData> products = objectMapper.readValue(
                                    dataNode.toString(),
                                    objectMapper.getTypeFactory().constructCollectionType(List.class, GoodsData.class)
                            );

                            String filterBrand = to.getBrand();
                            if (StringUtils.isNotBlank(filterBrand)) {
                                products = products.stream()
                                        .filter(item -> item.getBrandName().toLowerCase().contains(filterBrand.toLowerCase()))
                                        .collect(Collectors.toList());
                            }

                            if (products != null && !products.isEmpty()) {
                                QuoteVO title = new QuoteVO();
                                title.setSource("圣禾堂");
                                List<QuoteVO> children = new ArrayList<>();

                                for (GoodsData item : products) {
                                    QuoteVO tem = new QuoteVO();
                                    tem.setPart(item.getGoodsSn());
                                    tem.setMfc(String.valueOf(item.getModelName()));
                                    tem.setQty(to.getQty());
                                    tem.setMinNum(item.getMoq());
                                    tem.setVenPackage(item.getEncapsulationValue());
                                    tem.setSource("圣禾堂");
                                    tem.setModel(item.getDescription());
                                    tem.setBrand(item.getBrandName());
                                    tem.setCurrency(to.getCurrency());

                                    tem.setPrice(item.generatePriceString(to.getCurrency()));
                                    tem.setPrice2(item.generatePriceString(to.getCurrency()));
                                    tem.setPriceNum(item.generateNumString(to.getCurrency()));
                                    tem.setInventory(String.valueOf(item.getStockNum()));

                                    if (to.getQty() != null) {
                                        item.findMaxLadderNumberLessThanOrEqual(to.getQty(), to.getCurrency(), tem);
                                    }
                                    children.add(tem);
                                }
                                title.setChildren(children);
                                result.add(title);
                            }
                        }
                    }
                } else {
                    System.out.println("Request Failed.");
                }

                conn.disconnect();
            }
        } catch (Exception e) {
            // Exception is handled here but no specific handling is performed
            e.printStackTrace();
        }


        if (StringUtils.isNotBlank(to.getNo()))
            sortChildrenBySimilarity(result, to.getNo());
        return result;

    }


    @Override
    public BaseResult query(QuoteTO to) throws JsonProcessingException {


        List<QuoteVO> result = new ArrayList<>();

        // Use a fixed thread pool with a reasonable number of threads
        ExecutorService executor = Executors.newFixedThreadPool(10);
        List<Future<List<QuoteVO>>> futures = new ArrayList<>();

        try {
            // Process Excel data
            if (to.getExcel() != null) {
                if (to.getExcel().isEmpty()) {
                    return new BaseResult();
                }

                logger.info("开始批量查询，数量为" + to.getExcel().size());

                int count = 0;  // 计数器，用于限制最多处理前20条数据

                for (Map<String, Object> map : to.getExcel()) {
                    if (count >= 20) {
                        break;  // 如果已经处理了20条数据，跳出循环
                    }

                    QuoteTO tem = new QuoteTO();

                    Object value = map.get("Part Number");
                    if (value instanceof String) {
                        tem.setNo((String) value);
                    } else if (value instanceof Long || value instanceof Integer || value instanceof Double) {
                        tem.setNo(value.toString()); // Convert Long to String
                    }

                    if (StringUtils.isBlank(tem.getNo())) {
                        continue;
                    }

                    tem.setNo(filterZeroWidthSpace(tem.getNo()));


                    // 下面是将其他字段赋值的代码
                    Object countValue = map.get("(pieces)");
                    if (countValue instanceof String) {
                        // 如果是字符串，尝试转换为 Integer
                        tem.setQty(Integer.parseInt((String) countValue));
                    } else if (countValue instanceof Integer) {
                        // 如果已经是 Integer，直接设置
                        tem.setQty((Integer) countValue);
                    }

                    tem.setCurrency(to.getCurrency());
                    tem.setSource(to.getSource());

                    // 提交任务到执行器服务
                    Future<List<QuoteVO>> future = executor.submit(() -> singleRequest(tem));
                    futures.add(future);

                    // 增加计数器
                    count++;
                }

            } else if (to != null && StringUtils.isNotBlank(to.getNo())) {
                to.setNo(filterZeroWidthSpace(to.getNo()));
                Future<List<QuoteVO>> future = executor.submit(() -> singleRequest(to));
                futures.add(future);
            }

            // Collect the results
            for (Future<List<QuoteVO>> future : futures) {
                try {
                    result.addAll(future.get(10, TimeUnit.MINUTES)); // Adjust timeout as needed
                } catch (InterruptedException | ExecutionException | TimeoutException e) {
                    // Handle exceptions (e.g., log them)
                    e.printStackTrace();
                }
            }

        } finally {
            // Shut down the executor service
            executor.shutdown();
            try {
                // Await termination with a timeout to ensure shutdown completes
                if (!executor.awaitTermination(1, TimeUnit.MINUTES)) {
                    executor.shutdownNow();
                }
            } catch (InterruptedException e) {
                executor.shutdownNow();
            }
        }

        return new BaseResult(result);
    }

    @Override
    public List<QuoteCount> statistics() {
        Wrapper<QuoteCount> queryWrapper = new QueryWrapper<>();
        List<QuoteCount> quoteCounts = countMapper.selectList(queryWrapper);

        Map<Integer, String> typeNameMap = new HashMap<>();
        typeNameMap.put(1, "昴氏(上海)电子贸易有限公司");
        typeNameMap.put(2, "得捷电子(上海)有限公司");
        typeNameMap.put(3, "易络盟电子(中国)有限公司");
        typeNameMap.put(4, "云汉芯城(上海)互联网科技股份有限公司");
        typeNameMap.put(5, "圣禾堂(深圳)电子科技有限公司");
        quoteCounts = quoteCounts.stream()
                .peek(quoteCount -> {
                    // 根据 type 设置 typeName
                    String name = typeNameMap.get(quoteCount.getType());
                    quoteCount.setTypeName(name);
                })
                .collect(Collectors.toList());


        return quoteCounts;

    }


    public static void findMatchingPrices(Response.Item item, int number, QuoteVO tem) {
        List<Response.Item.Pricing> standardPricing = item.getStandardPricing();
        List<Response.Item.Pricing> myPricing = item.getMyPricing();

        // 找到在 StandardPricing 中小于等于输入数量的最大 BreakQuantity
        Response.Item.Pricing matchedStandard = null;
        for (Response.Item.Pricing pricing : standardPricing) {
            if (pricing.getQuantity() <= number) {
                if (matchedStandard == null || pricing.getQuantity() > matchedStandard.getQuantity()) {
                    matchedStandard = pricing;
                }
            }
        }

        // 如果在 StandardPricing 中没有找到匹配项，返回空
        if (matchedStandard == null) {
            return;
        }

        // 首先尝试找到与 matchedStandard 完全匹配的 MyPricing
        Response.Item.Pricing matchedMy = null;
        for (Response.Item.Pricing my : myPricing) {
            if (my.getQuantity() == matchedStandard.getQuantity()) {
                matchedMy = my;
                break;
            }
        }

        // 如果没有找到完全匹配的项，则寻找最接近但小于 matchedStandard 的项
        if (matchedMy == null) {
            Response.Item.Pricing closestSmaller = null;
            for (Response.Item.Pricing my : myPricing) {
                if (my.getQuantity() < matchedStandard.getQuantity()) {
                    if (closestSmaller == null || my.getQuantity() > closestSmaller.getQuantity()) {
                        closestSmaller = my;
                    }
                }
            }
            matchedMy = closestSmaller;
        }

        // 设置结果到 QuoteVO 对象
        tem.setResult(Integer.valueOf(matchedStandard.getQuantity()).toString());
        tem.setResult1(matchedMy != null ? matchedMy.getPrice() : matchedStandard.getPrice());
        tem.setResult2(matchedStandard.getPrice());

        if (matchedMy == null || matchedMy.getPrice() == null) {
            tem.setResult4(BigDecimal.ZERO.toString());
        } else {
            BigDecimal standardPrice = new BigDecimal(matchedStandard.getPrice());
            BigDecimal myPrice = new BigDecimal(matchedMy.getPrice());
            tem.setResult4(myPrice.divide(standardPrice, 2, BigDecimal.ROUND_HALF_UP).toString());
        }
    }


    public static void findMatchingPrices(ResponseDeJie.Item item, int number, QuoteVO tem) {
        List<ResponseDeJie.Item.Pricing> standardPricing = item.getStandardPricing();
        List<ResponseDeJie.Item.Pricing> myPricing = item.getMyPricing();

        // Find the largest BreakQuantity in StandardPricing that is less than or equal to the input number
        ResponseDeJie.Item.Pricing matchedStandard = null;
        for (ResponseDeJie.Item.Pricing pricing : standardPricing) {
            if (pricing.getBreakQuantity() <= number) {
                if (matchedStandard == null || pricing.getBreakQuantity() > matchedStandard.getBreakQuantity()) {
                    matchedStandard = pricing;
                }
            }
        }

        // If no match found in StandardPricing, return empty
        if (matchedStandard == null) {
            return;
        }

        // Find corresponding MyPricing based on the matched BreakQuantity
        ResponseDeJie.Item.Pricing matchedMy = null;
        for (ResponseDeJie.Item.Pricing my : myPricing) {
            if (my.getBreakQuantity() == matchedStandard.getBreakQuantity()) {
                matchedMy = my;
                break;
            }
        }

        // If no exact match found, look for the closest smaller BreakQuantity
        if (matchedMy == null) {
            ResponseDeJie.Item.Pricing closestSmaller = null;
            for (ResponseDeJie.Item.Pricing my : myPricing) {
                if (my.getBreakQuantity() < matchedStandard.getBreakQuantity()) {
                    if (closestSmaller == null || my.getBreakQuantity() > closestSmaller.getBreakQuantity()) {
                        closestSmaller = my;
                    }
                }
            }
            matchedMy = closestSmaller;
        }

        // Set results in the QuoteVO object
        tem.setResult(Integer.valueOf(matchedStandard.getBreakQuantity()).toString());
        tem.setResult1(matchedMy != null ? matchedMy.getUnitPrice() : "-");
        tem.setResult2(matchedStandard.getUnitPrice());

        if (matchedMy == null) {
            tem.setResult4(BigDecimal.ZERO.toString());
        } else if (StringUtils.isBlank(matchedMy.getUnitPrice())) {
            tem.setResult4("/");
        } else {
            BigDecimal standardPrice = new BigDecimal(matchedStandard.getUnitPrice());
            BigDecimal myPrice = new BigDecimal(matchedMy.getUnitPrice());
            tem.setResult4(myPrice.divide(standardPrice, 2, BigDecimal.ROUND_HALF_UP).toString());
        }
    }


    //数量
    public static String formatPrices3(List<ResponseElement.Product.Price> prices) {
        return prices.stream()
                .map(p -> String.format("%d~%d",
                        p.getFrom(),
                        p.getTo()

                ))
                .collect(Collectors.joining("<br/>"));
    }


    //标准价
    public static String formatPrices2(List<ResponseElement.Product.Price> prices) {
        return prices.stream()
                .map(p -> String.format("%.4f",

                        p.getPrice()
                ))
                .collect(Collectors.joining("<br/>"));
    }


    //折扣价
    public static String formatPrices(List<ResponseElement.Product.Price> prices) {
        return prices.stream()
                .map(p -> String.format("%.4f",

                        p.getCost()

                ))
                .collect(Collectors.joining("<br/>"));
    }

    public static void findPriceForValue2(IqcProduct product, int target, QuoteVO tem, String currency) {
        List<Double> price = new ArrayList<>();
        if (currency.equals("USD")) {
            price = product.getUsd();
        } else {
            price = product.getRmb();
        }


        if (product.getNums() == null || product.getNums().isEmpty() || price == null || price.isEmpty()) {
            return;
        }

        // Variables to store the closest match
        Integer closestNum = null;
        Double correspondingRmb = null;
        // Iterate over the nums list to find the closest match
        for (int i = 0; i < product.getNums().size(); i++) {
            Integer num = product.getNums().get(i);
            if (num <= target) {
                if (closestNum == null || num > closestNum) {
                    closestNum = num;
                    correspondingRmb = price.get(i);
                    tem.setResult2(String.valueOf(correspondingRmb));
                    tem.setResult(String.valueOf(closestNum));
                    tem.setResult1(String.valueOf(correspondingRmb));
                    tem.setResult4(BigDecimal.ZERO.toString());
                    break;
                }
            }
        }
    }


    //匹配结果
    public static void findPriceForValue(List<ResponseElement.Product.Price> prices, List<ResponseElement.Product.Price> stdPrices,
                                         int value, QuoteVO tem) {
        Optional<ResponseElement.Product.Price> matchingPrice = prices.stream()
                .filter(p -> value >= p.getFrom() && value <= p.getTo())
                .findFirst();

        Optional<ResponseElement.Product.Price> matchingEPrice = stdPrices.stream()
                .filter(p -> value >= p.getFrom() && value <= p.getTo())
                .findFirst();

        matchingPrice.ifPresent(p -> {
            tem.setResult(String.format("%d~%d", p.getFrom(), p.getTo()));
            tem.setResult1(p.getCost().toString());
            tem.setResult4("0.9");

        });

        matchingEPrice.ifPresent(p -> {
            tem.setResult2(p.getPrice().toString());
        });

        if (matchingPrice.isEmpty()) {
            tem.setResult("-");
            tem.setResult1(BigDecimal.ZERO.toString());
            tem.setResult4(BigDecimal.ZERO.toString());
        }
        if (matchingEPrice.isEmpty()) {
            tem.setResult2(BigDecimal.ZERO.toString());
        }
    }


    //排序，保证TR在最前面
    public void sortProductVariations(List<ResponseDeJie4.ProductVariation> productVariations) {
        productVariations.sort(Comparator
                .comparing((ResponseDeJie4.ProductVariation variation) -> {
                    String packageName = variation.getPackageType() != null ? variation.getPackageType().getName() : null;
                    if (packageName == null) {
                        return 2; // 先排序空值
                    }
                    if (packageName.contains("TR") || packageName.contains("TB")) {
                        return 0; // 排在最前
                    }
                    if (packageName.contains("Digi-Reel")) {
                        return 2; // 排在最后
                    }
                    return 1; // 其他情况中间
                })
                .thenComparing(variation ->
                                variation.getPackageType() != null ? variation.getPackageType().getName() : "",
                        Comparator.nullsLast(Comparator.naturalOrder()))
        );
    }

    public static int getLevenshteinDistance(String s1, String s2) {
        int lenS1 = s1.length();
        int lenS2 = s2.length();
        int[][] dp = new int[lenS1 + 1][lenS2 + 1];

        for (int i = 0; i <= lenS1; i++) {
            for (int j = 0; j <= lenS2; j++) {
                if (i == 0) {
                    dp[i][j] = j;
                } else if (j == 0) {
                    dp[i][j] = i;
                } else {
                    int cost = (s1.charAt(i - 1) == s2.charAt(j - 1)) ? 0 : 1;
                    dp[i][j] = Math.min(Math.min(dp[i - 1][j] + 1, dp[i][j - 1] + 1), dp[i - 1][j - 1] + cost);
                }
            }
        }

        return dp[lenS1][lenS2];
    }

    public void sortChildrenBySimilarity(List<QuoteVO> result, String no) {
        for (QuoteVO quote : result) {
            // 获取每个QuoteVO的children列表
            List<QuoteVO> children = quote.getChildren();
            if (children != null && !children.isEmpty()) {
                // 根据mfc与no的相似度进行排序
                Collections.sort(children, new Comparator<QuoteVO>() {
                    @Override
                    public int compare(QuoteVO q1, QuoteVO q2) {
                        String mfc1 = q1.getMfc();
                        String mfc2 = q2.getMfc();

                        // 计算mfc和no之间的Levenshtein距离
                        int distance1 = getLevenshteinDistance(mfc1, no);
                        int distance2 = getLevenshteinDistance(mfc2, no);

                        // 返回相似度比较结果：距离小的排前面，表示相似度高
                        return Integer.compare(distance1, distance2);
                    }
                });
            }
        }
    }


    /**
     * 远程调用接口查询询价接口
     *
     * @param dto
     * @return
     */
    @Override
    public List<ComponentPriceVO> queryRemoteApi(RemoteApiQuoteTO dto) {
        LoginResponse loginResponse = doLogin("26827", "123456");
        if (Objects.isNull(loginResponse) || !Objects.equals(loginResponse.getCode(), 0) || Objects.isNull(loginResponse.getData())) {
            logger.error("调用远程登录接口报错{}", loginResponse.toString());
            throw new RuntimeException("调用远程登录接口报错");
        }
        LoginResponse.LoginData data = loginResponse.getData();
        String accessToken = data.getAccessToken();
        if (Objects.isNull(dto.getExcel())) {
            return doRemoteApiQueryComponentData(accessToken, dto);
        } else {
            List<Map<String, Object>> excel = dto.getExcel();
            if (excel.isEmpty()) {
                logger.warn("Excel数据为空，返回空列表");
                return Collections.emptyList();
            }

            // 使用CompletableFuture并行处理Excel中的每一行数据
            List<CompletableFuture<List<ComponentPriceVO>>> futures = excel.stream()
                    .map(rowData -> CompletableFuture.supplyAsync(() -> {
                        // 根据行数据组装新的查询DTO
                        RemoteApiQuoteTO rowDto = assembleDtoFromExcelRow(dto, rowData);
                        return doRemoteApiQueryComponentData(accessToken, rowDto);
                    }, componentExecutor)) // 建议使用自定义线程池
                    .toList();

            // 等待所有异步任务完成并收集结果


            return futures.stream()
                    .map(CompletableFuture::join)
                    .flatMap(Collection::stream)
                    .toList();

        }
    }

    public List<ComponentPriceVO> groupBySupplierCode(List<ComponentPriceVO> data) {
        // 按supplierCode分组，处理可能的null值
        Map<String, List<ComponentPriceVO>> groupedMap = data.stream().filter(x -> Objects.nonNull(x.getStockInfo()))
                .collect(Collectors.groupingBy(price ->
                        // 安全获取supplierCode，避免空指针
                        Optional.ofNullable(price.getStockInfo())
                                .map(ComponentStockVO::getSupplierCode)
                                .orElse(null)
                ));

        // 为每个分组创建父对象并设置children
        List<ComponentPriceVO> result = new ArrayList<>();
        for (Map.Entry<String, List<ComponentPriceVO>> entry : groupedMap.entrySet()) {
            String supplierCode = entry.getKey();
            List<ComponentPriceVO> children = entry.getValue();

            // 创建父对象
            ComponentPriceVO parent = new ComponentPriceVO();
            // 设置父对象的supplierCode（通过stockInfo关联）
            ComponentStockVO parentStock = new ComponentStockVO();
            parentStock.setSupplierCode(supplierCode);
            parent.setStockInfo(parentStock);
            // 设置子对象列表
            parent.setChildren(children);

            result.add(parent);
        }

        return result;
    }

    /**
     * 根据Excel行数据组装查询DTO
     *
     * @param originalDto
     * @param rowData
     * @return
     */
    private RemoteApiQuoteTO assembleDtoFromExcelRow(RemoteApiQuoteTO originalDto, Map<String, Object> rowData) {
        // 复制原始DTO的基本属性
        RemoteApiQuoteTO newDto = new RemoteApiQuoteTO();
        newDto.setStockType(1);
        newDto.setCurrency(originalDto.getCurrency());
        newDto.setModel(Objects.isNull(rowData.get("Part Number")) ? null : String.valueOf(rowData.get("Part Number")));
        newDto.setNum(Objects.isNull(rowData.get("(pieces)")) ? null : Long.valueOf(String.valueOf(rowData.get("(pieces)"))));
        newDto.setSupplier(originalDto.getSupplier());
        return newDto;
    }


    /**
     * 执行登录操作
     *
     * @param username 用户名
     * @param password 密码
     * @return 登录响应对象
     */
    public LoginResponse doLogin(String username, String password) {
        // 创建登录请求参数对象
        LoginRequest request = new LoginRequest(username, password);

        HttpResponse response = HttpRequest.post("http://192.168.10.24:48080/admin-api/system/auth/login")
                .contentType("application/json")
                .body(JSONUtil.toJsonStr(request))
                .timeout(30000)  // 超时时间30秒
                .execute();
        return JSONUtil.toBean(response.body(), LoginResponse.class);
    }

    /**
     * 执行远程调用api操作
     *
     * @param accessToken 用户名
     * @param dto         密码
     * @return 登录响应对象
     */
    public List<ComponentPriceVO> doRemoteApiQueryComponentData(String accessToken, RemoteApiQuoteTO dto) {
        HttpResponse response = HttpRequest.post("http://192.168.10.24:48080/admin-api/quote/forRemote/queryList")
                .header("Content-Type", "application/json")
                .header("Authorization", "Bearer " + accessToken)
                .body(JSONUtil.toJsonStr(dto))
                .execute();

        RemoteCommonResult bean = JSONUtil.toBean(response.body(), RemoteCommonResult.class);
        if (Objects.isNull(bean) || !Objects.equals(bean.getCode(), 0) || Objects.isNull(bean.getData())) {
            logger.error("调用远程查询询价接口报错{}", bean.toString());
            throw new RuntimeException("调用远程查询询价接口报错");
        }
        return bean.getData();
    }
}
